//
//  File.swift
//  BasicTools
//
//  Created by ikang on 2025/7/22.
//

import Foundation

extension BasicWrapper where Base == String {
    
    // 验证身份证
    public func validIDCard() -> Bool {
        guard self.base.count == 18 else { return false }
        
        // 2. 正则表达式校验基本格式
        let pattern = "^[1-9]\\d{5}(18|19|20)\\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\\d|3[01])\\d{3}[0-9Xx]$"
        let regex = try? NSRegularExpression(pattern: pattern)
        let range = NSRange(location: 0, length: self.base.count)
        guard let match = regex?.firstMatch(in: self.base, options: [], range: range) else {
            return false
        }
        
        // 3. 校验码验证（仅对18位身份证）
        return checkIDCardLastDigit(self.base)
    }

    
    private func checkIDCardLastDigit(_ id: String) -> Bool {
        let weights = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
        let checkDigits = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"]
        
        var sum = 0
        for i in 0..<17 {
            let char = id[id.index(id.startIndex, offsetBy: i)]
            guard let digit = Int(String(char)) else { return false }
            sum += digit * weights[i]
        }
        
        let mod = sum % 11
        let lastChar = id.last!.uppercased()
        return lastChar == checkDigits[mod]
    }
    
    // 验证手机号
    public func validPhoneNumber() -> Bool {
        // 移动号段
        let cm = "(^1(3[4-9]|4[7]|5[0-27-9]|7[8]|8[2-478])\\d{8}$)|(^1705\\d{7}$)"
        // 联通号段
        let cu = "(^1(3[0-2]|4[5]|5[56]|7[6]|8[56])\\d{8}$)|(^1709\\d{7}$)"
        // 电信号段
        let ct = "(^1(33|53|77|8[019])\\d{8}$)|(^1700\\d{7}$)"
        
//        let pattern = "^1[0-9]{10}$"
//        let predicate = NSPredicate(format: "SELF MATCHES %@", pattern)
//        return predicate.evaluate(with: phone)
        
        let cmPredicate = NSPredicate(format: "SELF MATCHES %@", cm)
        let cuPredicate = NSPredicate(format: "SELF MATCHES %@", cu)
        let ctPredicate = NSPredicate(format: "SELF MATCHES %@", ct)
        
        return  cmPredicate.evaluate(with: self.base) ||
                cuPredicate.evaluate(with: self.base) ||
                ctPredicate.evaluate(with: self.base)
    }
}
